import { Button, Input, message } from 'antd';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import cn from 'classnames';
import { observer } from '@formily/react';
import SearchImgPanel from '../SmallPanelView/SearchImgPanel';
import { InbizIcon, h5Utils } from '@inbiz/utils';
import { TextWidget, getMessage } from '@inbiz/react';
import LabelConfigSelect from './LabelConfigSelect';
import { SearchResultPanel } from '../SearchResultPanel';
import SmallPanelInput from '../SmallPanelView/SmallPanelInput';
import { useSearchUIState } from '../../../../store/hooks/useSearchUIState';
import { useJumpResult } from '../../../../store/hooks/useJumpResult';
import { useViewType } from '../../../../store/hooks/useViewType';
import { useSearchUIDispatch } from '../../../../store/hooks/useSearchUIDispatch';
import { useIndexRange } from '../../../../store/hooks/useIndexRange';
import { useResultSearch } from '../../../../store/hooks/useResultSearch';
import { useConfigEventsApi, useSearchPropsState } from '../../../../store/hooks/useSearchPropsState';
import type { ReactElement, MouseEvent } from 'react'
interface IProps {
  buttonText?: {
    status: boolean;
    value: string;
  };
  smallPanelViewInputClassName: string,
  inputwidth: number
}

export const SearchInputView = observer((props: IProps & any): ReactElement => {
  const { visible, customPlaceholderText, placeholderWeb, customFolderId, $visible, smallPanelViewInputClassName = '', inputwidth, inbiz, controlId } = props;
  const { selectShowTab, showSearchResultPanel, keyword, keywords, searchBtnWidth, historyDataLength, quickDataLength, panelId, showTag } = useSearchUIState();
  const { pullWidth, endSearchIcon, buttonIcon, quikSearch, searchIcon } = useSearchPropsState();
  const viewType = useViewType();
  const updateUIState = useSearchUIDispatch();
  const indexRange = useIndexRange();
  const resultSearch = useResultSearch();
  const [uploadData, $uploadData] = useState<any>({});
  const stop = useRef<boolean>(false);
  const searchInput = useRef<any>();
  const [hoverIndex, $hoverIndex] = useState<number | undefined>(undefined);
  const [maxIndex, $maxIndex] = useState<number>(7);
  const divRef = useRef<HTMLDivElement>(null)
  const [inputTemp, $inputTemp] = useState('')
  const { configEvents } = useConfigEventsApi();
  useEffect(() => {
    if (panelId == 'quickSearch') {
      $maxIndex(quickDataLength)
    } else {
      $maxIndex(historyDataLength)
    }
  }, [historyDataLength, quickDataLength])

  useEffect(() => {
    $inputTemp(keywords[keywords.length - 1])
  }, [keywords])

  // 输入事件
  const onSearchChange = useCallback((e) => {
    $hoverIndex(undefined);
    if (!visible) {
      updateUIState({
        panelId: e.target.value && smallPanelViewInputClassName ? 'quickSearch' : 'historySearch',
        showGraph: false,
      });
      if (smallPanelViewInputClassName) {
        updateUIState({
          // 为了判断是否显示快速搜索, 不显示快速搜索,也不显示面板, 但没有KeyWord又要显示历史记录
          showSearchResultPanel: e.target.value ? quikSearch ? true : false : true,
        });
      } else {
        updateUIState({
          showSearchResultPanel: true,
        });
      }
      $visible(false)
    }
    $inputTemp(e.target.value)
    updateUIState({
      keyword: e.target.value,
    });
  }, [visible]);

  // 获得焦点
  const onSearchFocus = useCallback(() => {
    if (stop.current) {
      stop.current = false;
      return;
    }
    $hoverIndex(undefined);
    updateUIState({
      panelId: keyword && smallPanelViewInputClassName ? 'quickSearch' : 'historySearch', // 只有小面板才有快速搜索
      showTag: true
    });
    if (smallPanelViewInputClassName) {
      updateUIState({
        // 为了判断是否显示快速搜索, 不显示快速搜索,也不显示面板, 但没有KeyWord又要显示历史记录
        showSearchResultPanel: keyword ? quikSearch ? true : false : true,
      });
    } else {
      updateUIState({
        showSearchResultPanel: true,
        showGraph: false
      });
    }
  }, [keyword, showSearchResultPanel, visible, stop.current]);

  // 键盘选中
  const $divRef = useRef<HTMLDivElement>(null);
  useEffect(() => {
    const $quickSearchitem = document?.querySelector('.selectItem')
    if ($quickSearchitem) {
      $quickSearchitem?.scrollIntoView()
    }
  }, [hoverIndex])

  const clearStorage = () => {
    localStorage.removeItem('_searchEngineStatus')
    sessionStorage.removeItem('_searchEngineStatus')
  }
  useEffect(() => {
    const handleKeyDown = (e: { keyCode: number } & MouseEvent) => {
      if (e.keyCode === 40 || e.keyCode === 38) { // 箭头下 箭头上
        const smallViewPopover = document.querySelector('.smallViewPopover');
        const $quickSearchitem = smallViewPopover?.querySelector('.selectItem');
        // const max = panelId == 'quickSearch' ? (smallViewPopover?.querySelectorAll('._quick_search').length || 0) - 1 : maxIndex;
        const max = maxIndex
        $hoverIndex((i) => {
          if (!i && isNaN(i)) {
            i = -1
          }

          if ($quickSearchitem) {
            $quickSearchitem?.scrollIntoView()
          }
          if (e.keyCode === 40) {
            return i + 1 >= max ? max : i + 1;
          } else {
            return i - 1 <= -1 ? 0 : i - 1;
          }
        });
        e.stopPropagation();
        e.preventDefault()
      }
      if (e.keyCode === 13) { // enter
        const $item = document?.querySelector('.historyitemhover') || document?.querySelector('.search-result-list li.hover');
        const searchDataSourceItem = document?.querySelector('.selectItem')
        if ($item) {
          //@ts-ignore
          $item.click();
          e.stopPropagation(); // 只能分开, 不能提出, 会影响enter键搜索
        } else if (searchDataSourceItem) {
          searchDataSourceItem.click()
          e.stopPropagation();
        }
      }
      if (e.keyCode === 27) { // esc
        updateUIState({
          showSearchResultPanel: false,
        });
        // $showOriginSearch(false)
      }
      if (e.keyCode == 8) {
        // 为什么要加这个监听呢?
        if (searchInput.current) {
          updateUIState({ keyword: searchInput.current.input.value });
        }
      }
    };
    document.addEventListener('keydown', handleKeyDown, true);
    return () => {
      document.removeEventListener('keydown', handleKeyDown, true);
    };
  }, [showSearchResultPanel, maxIndex]);

  // 点击搜索
  const onJumpResult = useJumpResult();
  const onSearch = useCallback(
    (value: string, result?: boolean, folderId?: string) => {
      if (visible) {
        if (value.startsWith('http') && value.includes('fileid')) {
          const searchParams = new URL(value).searchParams
          const mark = searchParams.get('fileid')
          $uploadData({
            nResult: 0,
            mark
          })
        }
      } else if (value) {
        const newKeys: string[] = keywords || [];
        if (result && (!newKeys.includes(value) || !value)) {
          newKeys.push(value);
        }

        const searchTxt = result ? newKeys : [value];
        onJumpResult(searchTxt[0], searchTxt, undefined, {
          isResultButton: result,
          currentValue: value,
          customFolderId: smallPanelViewInputClassName && showTag ? folderId ?? customFolderId : '' // 暂时只有小面板视图生效
        });
        updateUIState({
          showSearchResultPanel: false,
          keywords: searchTxt,
          showGraph: false,
          keyword: result ? '' : keyword,
        });

      } else {
        message.warn({
          content: getMessage('SearchEngine.pleaseEnterKeywords'),
          key: 'warnmessage'
        })
      }

    },
    [onJumpResult, updateUIState, keywords, smallPanelViewInputClassName, customFolderId, showTag],
  );

  // 设置搜索按钮宽度
  const setWindowWidth = () => {
    const btn: any = $divRef.current?.querySelector(`#${controlId}_searchBtn`);
    const width: number = btn?.clientWidth || 150;
    updateUIState({
      searchBtnWidth: width,
    });
  };
  useEffect(() => {
    setWindowWidth();
  }, []);

  // 以图搜图-搜索
  useEffect(() => {
    if (uploadData && JSON.stringify(uploadData) !== '{}') {
      if (uploadData?.nResult === 0) {
        updateUIState({
          showSearchResultPanel: false,
          keyword: '',
          keywords: [''],
          showGraph: false,
        });
        $visible(false);
        onJumpResult('', [], uploadData.mark);
      } else {
        message.error('图片上传失败');
        if (uploadData.url) {
          location.href = uploadData.url;
        }
      }
    }
  }, [uploadData]);
  // 判断结果中检索的位置
  const showResultPosition = useMemo(() => {
    return !!(buttonIcon?.type || searchIcon?.type || props?.buttonText?.status);
  }, [buttonIcon?.type, searchIcon?.type, props?.buttonText]);

  // 结果中检索
  const ResultSearch = useMemo(() => {
    const content = <Button
      type="primary"
      id={`${controlId}_searchResultBtn`}
      icon={
        endSearchIcon?.type &&
        endSearchIcon.type !== '' && (
          <InbizIcon
            type={endSearchIcon?.type || ''}
            style={{
              marginRight: resultSearch.value !== '' ? 12 : 0, fontSize: 20, display: 'flex',
              alignItems: 'center', color: '#fff'
            }}
          />
        )
      }
      onClick={() => {
        onSearch(keyword || '', true);
      }}
    >
      <TextWidget>{resultSearch?.value || ''}</TextWidget>
    </Button>
    return resultSearch?.status && viewType !== 'smallPanelView' ? (
      showResultPosition ? <div className="result-search-box">
        {content}
      </div> : content
    ) : null
  }, [showResultPosition, resultSearch, viewType, endSearchIcon, onSearch]);
  return (
    <>
      {/* 搜索框 */}
      <div
        className={cn('search-input-container', {
          'dms-container': selectShowTab?.isDMS,
          'smallPanelViewInputClassName': smallPanelViewInputClassName
        })}
        ref={$divRef}
        onClick={() => {
          // isClickContent.current = true;
        }}
      >
        {smallPanelViewInputClassName ? <SmallPanelInput
          {...props}
          indexRange={indexRange}
          onSearchChange={onSearchChange}
          onSearchFocus={onSearchFocus}
          onSearch={onSearch}
          smallPanelViewInputClassName={smallPanelViewInputClassName}
          placeholderText={customPlaceholderText}
          stop={stop}
          $visible={$visible}
          inputwidth={inputwidth}
          visible={visible}
          $uploadData={$uploadData}
          hoverIndex={hoverIndex}
          clearStorage={clearStorage}
        /> : <div
          onClick={(e) => {
            h5Utils.inbizPageEvent.emit(props.controlId, true);
          }}
          ref={divRef}
          id={`${controlId}_searchInput`}
        >
          <Input.Search
            className={cn(`search-input-control ${Boolean(indexRange) ? '' : 'search-input-control_noindexrange'}`)}
            addonBefore={Boolean(indexRange) && <LabelConfigSelect searchDom={$divRef} />}
            size="large"
            ref={searchInput}
            onChange={onSearchChange}
            onFocus={onSearchFocus}
            maxLength={40}
            onSearch={(e) => onSearch(e, false)}
            value={inputTemp}
            placeholder={getMessage(placeholderWeb)}
            suffix={
              <span className="search-handles">
                {keyword && keyword !== '' && (
                  <InbizIcon
                    type="icon-ic-close-bold"
                    className="all-clear-action"
                    onMouseDown={(e) => {
                      e.stopPropagation()
                      e.preventDefault()
                      // stop.current = true;
                    }}
                    onClick={() => {
                      updateUIState({ keyword: '' });
                      $inputTemp('')
                      searchInput.current?.focus?.();
                      clearStorage()
                      configEvents.current?.onCustomClear?.()
                    }}
                  />
                )}
                {selectShowTab?.keywordAtlas && keyword && keyword !== '' ? (
                  <InbizIcon
                    type="icon-atlas-hover"
                    title={getMessage('SearchEngine.inform')}
                    onMouseDown={() => {
                      stop.current = true;
                    }}
                    onClick={() => {
                      updateUIState({ showGraph: true, showSearchResultPanel: false, })
                      $visible(false);
                    }}
                  />
                ) : selectShowTab?.imgSearchImg ? (
                  <InbizIcon
                    type="icon-ico-Searchforpictures"
                    onMouseDown={() => {
                      stop.current = true;
                    }}
                    title={getMessage('SearchEngine.imgSearchImg')}
                    onClick={(e: any) => {
                      e.stopPropagation();
                      e.preventDefault();
                      updateUIState({
                        showSearchResultPanel: false,
                        showGraph: false,
                      });
                      $visible(true);
                    }}
                  />
                ) : null}
              </span>
            }
            enterButton={
              showResultPosition ? <Button
                id={`${controlId}_searchBtn`}
                icon={
                  (buttonIcon?.type || searchIcon?.type) &&
                  <InbizIcon
                    className="search-btn-icon"
                    type={buttonIcon?.type || searchIcon?.type}
                    style={{
                      marginRight:
                        (props.buttonText?.status && props.buttonText?.value !== '') || (props.searchIcon?.status && props.searchIcon?.value !== '') ? 12 : 0,
                    }}
                  />
                }
                type="primary"
              >
                {props?.buttonText?.status ? (
                  <span className={cn('search-input-button-text')}>
                    <TextWidget>{props.buttonText?.value || props.searchIcon?.value || ''}</TextWidget>
                  </span>
                ) : null}
              </Button> : ResultSearch
            }
          />
        </div>
        }
        {/* 历史记录/搜索结果面板 */}
        {!!showSearchResultPanel && !smallPanelViewInputClassName && <SearchResultPanel {...props} hoverIndex={hoverIndex} />}
        {/* 以图搜图-图上传 */}
        {!smallPanelViewInputClassName && visible && <div
          className="image-upload-box"
          style={{ left: indexRange ? pullWidth + 1 : 0, right: searchBtnWidth + 1 }}
          onClick={() => {
            h5Utils.inbizPageEvent.emit(props.controlId, true);
          }}
        >
          <SearchImgPanel
            uploadUrl="/ImageSearch/Upload"
            visible={visible}
            $visible={$visible}
            divRef={divRef}
            customClassName='inlineStyleImg'
            onOk={(data: any) => {
              $uploadData({ ...data });
            }}
            onCancel={() => {
              $visible(false);
            }}
            close={true}
          />
        </div>}
      </div>
      {/* 结果中搜索 */}
      {showResultPosition && ResultSearch}
    </>
  );
});
SearchInputView.displayName = 'SearchInputView';
export default SearchInputView
